/**
 * 
 */
package org.jverify.utility;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * @author imavroukakis
 */
public final class FileDigest {

	static {
		Security.addProvider(new BouncyCastleProvider());
	}

	private FileDigest() {
	}

	/**
	 * Produces an SHA sum from a stream of bytes
	 * 
	 * @param fileName
	 *            A String representing the path to the file
	 * @return a <code>byte[]</code> array containing the SHA digest.
	 * @throws IOException
	 */
	public static byte[] calculateSum(final File file) throws IOException {

		FileChannel fChan = null;
		try {

			final MessageDigest messageDigest = MessageDigest.getInstance("SHA256", "BC");
			fChan = new FileInputStream(file).getChannel();
			final int fSize = fChan.size() >= Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) fChan.size();
			final ByteBuffer bBuff = ByteBuffer.allocate(fSize);
			fChan.read(bBuff);
			bBuff.rewind();
			messageDigest.update(bBuff);
			return messageDigest.digest();
		}
		catch (final NoSuchAlgorithmException e) {
			throw new IllegalStateException(e);
		}
		catch (final NoSuchProviderException e) {
			throw new IllegalStateException(e);
		}
		finally {
			if (fChan != null) {
				fChan.close();
			}
		}
	}

	public static byte[] getBytes(final File file) throws IOException {
		final FileChannel fileChannel = new FileInputStream(file).getChannel();
		final int size = (int) fileChannel.size();
		final byte[] bytes = new byte[size];
		final ByteBuffer byteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, size);
		byteBuffer.get(bytes);
		fileChannel.close();
		return CompressedStreamHandler.compressData(bytes);
	}

}
